//
//  WNPhotoManager.swift
//  WalkNovel
//
//  Created by Kevin on 2023/7/4.
//

import UIKit
import Photos
import RxSwift
import Alamofire
import HandyJSON
import Foundation
import UserNotifications

class WNPhotoManager: NSObject, UIImagePickerControllerDelegate,
                      UINavigationControllerDelegate {
    
    static let shared = WNPhotoManager()
    
    var imgPickerVC: UIImagePickerController?
    
    var picImage: UIImage?
    
    var avatarClosure: StringClosure?
    
    var purposeType = 0
    
    // 检查权限是否开启
    func wn_openPhotoImage(_ type: Int) {
        if wn_authorizeStatus() {
            purposeType = type
            wn_getTopVC()?.wn_showActionSheet(nil, nil, "Take a picture", "Choose from album", firstAction: { [weak self] in
                self?.wn_imgPicker(1)
            }, secondAction: { [weak self] in
                self?.wn_imgPicker(0)
            })
        }
    }
    
    func wn_authorizeStatus() -> Bool {
        let status = PHPhotoLibrary.authorizationStatus()
        switch status {
        case .authorized:
            return true
        case .notDetermined:
            PHPhotoLibrary.requestAuthorization({ (status) -> Void in
                if status == .authorized {
                    WNThread.wn_runInMainThread {
                        self.wn_openPhotoImage(self.purposeType)
                    }
                }
            })
        default:
            WNThread.wn_runInMainThread {
                wn_getTopVC()?.wn_showAlert("Photo Access", "To enalbe access, Tap ‘Settings’ and trun on camera.", "Cancel", "Settings", firstAction: {} , secondAction: {
                    let url = URL(string: UIApplication.openSettingsURLString)
                    if let url = url, UIApplication.shared.canOpenURL(url) {
                        UIApplication.shared.open(url, options: [:], completionHandler: { (success) in
                        })
                    }
                })
            }
        }
        return false
    }
    
    func wn_notAuthorizeStatus(_ isEnable: @escaping (Bool) -> Void) {
        UNUserNotificationCenter.current().getNotificationSettings { settings in
            switch settings.authorizationStatus {
            case .authorized:
                WNThread.wn_runInMainThread {
                    isEnable(true)
                }
            default:
                WNThread.wn_runInMainThread {
                    isEnable(false)
                }
            }
        }
    }
    
    func wn_imgPicker(_ type: Int) {
        if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
            if self.imgPickerVC != nil {
                imgPickerVC = nil
                imgPickerVC?.delegate = nil
            }
            imgPickerVC = UIImagePickerController()
            imgPickerVC?.delegate = self
            imgPickerVC?.modalTransitionStyle = .coverVertical
            imgPickerVC?.allowsEditing = true
            if type == 1 {
                wn_getImgFromCamera()
            }else {
                wn_getImgFromPhoto()
            }
        }
    }
    
    // 相册
    func wn_getImgFromPhoto() {
        imgPickerVC?.sourceType = .photoLibrary
        if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
            imgPickerVC?.modalPresentationStyle = .overFullScreen
            wn_getTopVC()?.present(imgPickerVC!, animated: true, completion: nil)
        }else {
            WNHUD.wn_show("Album Unavailable")
        }
    }
    // 相机
    func wn_getImgFromCamera() {
        if UIImagePickerController.isSourceTypeAvailable(.camera) {
            imgPickerVC?.sourceType = .camera
            imgPickerVC?.videoQuality = .typeHigh
            imgPickerVC?.cameraCaptureMode = .photo
            imgPickerVC?.modalPresentationStyle = .overFullScreen
            wn_getTopVC()?.present(imgPickerVC!, animated: true, completion: nil)
        }else {
            WNHUD.wn_show("Camera Unavailable")
        }
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage, let cropRect = info[UIImagePickerController.InfoKey.cropRect] as? CGRect {
            picImage = cropImage(image, .init(x: 0, y: 0, width: cropRect.width, height: (purposeType == 0 ? cropRect.height : cropRect.height*9/16)))
            uploadImageRequst()
            picker.dismiss(animated: true, completion: nil)
        }
    }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }
    
    /// 上传图片
    func uploadImageRequst() {
        guard let image = picImage else { return }
        if purposeType == 0 {
            guard let imageData = imageZipToData(image) else { return }
            WNHUD.wn_showLoading()
            provider_user.rx.request(.uploadAvatar(imageData))
                .asObservable()
                .mapModel(BaseModel<String>.self)
                .subscribe(onNext: { [weak self] (model) in
                    WNHUD.wn_hide()
                    guard model.code == 0 else {
                        WNHUD.wn_show(model.msg ?? "")
                        return
                    }
                    if let url = model.data {
                        self?.avatarClosure?(url)
                    }
                }, onError: { (error) in
                    WNHUD.wn_show("Check the network connection")
                }).disposed(by: rx.disposeBag)
        }
    }
    
    func imageZipToData(_ image: UIImage) -> Data? {
        guard var data = image.jpegData(compressionQuality: 1.0) else {
            return nil
        }
        if data.count > 200*1024 {
            if data.count > 1024*1024 { // 1M以及以上
                data = image.jpegData(compressionQuality: 0.5)!
            }else if data.count > 512*1024 { // 0.5M-1M
                data = image.jpegData(compressionQuality: 0.6)!
            }else if data.count > 200*1024 { // 0.25M-0.5M
                data = image.jpegData(compressionQuality: 0.9)!
            }
        }
        return data
    }
    
    func cropImage(_ imageToCrop: UIImage, _ rect: CGRect) -> UIImage? {
        if let imageRef = imageToCrop.cgImage?.cropping(to: rect) {
            let cropped: UIImage = UIImage(cgImage: imageRef)
            return cropped
        }
        return nil
    }
}
